<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-hemisu.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-hemisu.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-hemisu.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="读书笔记,js高程,">










<meta name="description" content="[TOC] 本章内容 使用高级函数 防篡改对象 Yielding Timers">
<meta name="keywords" content="读书笔记,js高程">
<meta property="og:type" content="article">
<meta property="og:title" content="js高程读书笔记 第22章 高级技巧">
<meta property="og:url" content="http://www.hemisu.com/2017/09/08/310/index.html">
<meta property="og:site_name" content="何米酥`s Blog">
<meta property="og:description" content="[TOC] 本章内容 使用高级函数 防篡改对象 Yielding Timers">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2017-09-08T15:56:41.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="js高程读书笔记 第22章 高级技巧">
<meta name="twitter:description" content="[TOC] 本章内容 使用高级函数 防篡改对象 Yielding Timers">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":true,"scrollpercent":true,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://www.hemisu.com/2017/09/08/310/">





  <title>js高程读书笔记 第22章 高级技巧 | 何米酥`s Blog</title>
  








  <!-- Hotjar Tracking Code for www.hemisu.com -->
  <script>
      (function(h,o,t,j,a,r){
          h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
          h._hjSettings={hjid:1933736,hjsv:6};
          a=o.getElementsByTagName('head')[0];
          r=o.createElement('script');r.async=1;
          r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
          a.appendChild(r);
      })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
  </script>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">何米酥`s Blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">EFE</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br>
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br>
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://www.hemisu.com/2017/09/08/310/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="何米酥">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="何米酥`s Blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">js高程读书笔记 第22章 高级技巧</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-09-08T15:56:41+00:00">
                2017-09-08
              </time>
            

            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/笔记/" itemprop="url" rel="index">
                    <span itemprop="name">笔记</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>[TOC]</p>
<h1 id="本章内容"><a href="#本章内容" class="headerlink" title="本章内容"></a>本章内容</h1><ul>
<li>使用高级函数</li>
<li>防篡改对象</li>
<li>Yielding Timers<a id="more"></a>
<h1 id="高级函数"><a href="#高级函数" class="headerlink" title="高级函数"></a>高级函数</h1><h2 id="安全的类型检测"><a href="#安全的类型检测" class="headerlink" title="安全的类型检测"></a>安全的类型检测</h2>在任何值上调用Object原生的toString()方法，都会返回一个[object NativeConstructorName]格式的字符串。每个类在内部都有一个[[Class]]属性，这个属性中就指定了上述字符串中的构造函数名。</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isArray</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(value) == <span class="string">"[object Array]"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isFunction</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(value) == <span class="string">"[object Function]"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isRegExp</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(value) == <span class="string">"[object RegExp]"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isNativeJSON</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(value) == <span class="string">"[object JSON]"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="作用域安全的构造函数"><a href="#作用域安全的构造函数" class="headerlink" title="作用域安全的构造函数"></a>作用域安全的构造函数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name, age, job</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.name = name;</span><br><span class="line">    <span class="keyword">this</span>.age = age;</span><br><span class="line">    <span class="keyword">this</span>.job = job;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person1 = <span class="keyword">new</span> Person(<span class="string">"Nicholas"</span>, <span class="number">29</span>, <span class="string">"Software Engineer"</span>);</span><br><span class="line">alert(person1.name);     <span class="comment">//"Nicholas"</span></span><br><span class="line">alert(person1.age);      <span class="comment">//29</span></span><br><span class="line">alert(person1.job);      <span class="comment">//"Software Engineer"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person2 = Person(<span class="string">"Nicholas"</span>, <span class="number">29</span>, <span class="string">"Software Engineer"</span>);</span><br><span class="line">alert(person2);         <span class="comment">//undefined</span></span><br><span class="line">alert(<span class="built_in">window</span>.name);     <span class="comment">//"Nicholas"</span></span><br><span class="line">alert(<span class="built_in">window</span>.age);      <span class="comment">//29</span></span><br><span class="line">alert(<span class="built_in">window</span>.job);      <span class="comment">//"Software Engineer"</span></span><br></pre></td></tr></table></figure>
<p>问题出在如果没有使用new操作符来调用构造函数的情况下，会创建一个新的Person对象，同时会给它分配这些属性。直接调用Person，this会映射到全局对象windows上，导致错误对象属性的意外增加。</p>
<p>作用域安全的构造函数在进行任何更改前，首先确认this对象是正确类型的实例。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name, age, job</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span> <span class="keyword">instanceof</span> Person)&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">        <span class="keyword">this</span>.job = job;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Person(name, age, job);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person1 = Person(<span class="string">"Nicholas"</span>, <span class="number">29</span>, <span class="string">"Software Engineer"</span>);</span><br><span class="line">alert(<span class="built_in">window</span>.name);   <span class="comment">//""</span></span><br><span class="line">alert(person1.name);  <span class="comment">//"Nicholas"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person2 = <span class="keyword">new</span> Person(<span class="string">"Shelby"</span>, <span class="number">34</span>, <span class="string">"Ergonomist"</span>);</span><br><span class="line">alert(person2.name);  <span class="comment">//"Shelby"</span></span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Polygon</span>(<span class="params">sides</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span> <span class="keyword">instanceof</span> Polygon) &#123;</span><br><span class="line">        <span class="keyword">this</span>.sides = sides;</span><br><span class="line">        <span class="keyword">this</span>.getArea = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Polygon(sides);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Rectangle</span>(<span class="params">width, height</span>)</span>&#123;</span><br><span class="line">    Polygon.call(<span class="keyword">this</span>, <span class="number">2</span>);</span><br><span class="line">    <span class="keyword">this</span>.width = width;</span><br><span class="line">    <span class="keyword">this</span>.height = height;</span><br><span class="line">    <span class="keyword">this</span>.getArea = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.width * <span class="keyword">this</span>.height;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> rect = <span class="keyword">new</span> Rectangle(<span class="number">5</span>, <span class="number">10</span>);</span><br><span class="line">alert(rect.sides);   <span class="comment">//undefined</span></span><br></pre></td></tr></table></figure>
<p>这段代码中，Polygon构造函数是作用域安全的，然而Rectangle构造函数不是。新创建一个Rectangle实例之后，这个实例应该通过Polygon.call()来继承Polygon的sides属性。但是由于Polygon对象构造函数是作用域安全的，this对象并非Polygon的实例，所以会创建并返回一个新的Polygon对象。Rectangle构造函数中的this对象并没有得到增长，同时Polygon.call()返回的值也没有用到，所以Rectangle实例中就不会有sides属性。</p>
<p>使用原型链方式来解决这个问题。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Polygon</span>(<span class="params">sides</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span> <span class="keyword">instanceof</span> Polygon) &#123;</span><br><span class="line">        <span class="keyword">this</span>.sides = sides;</span><br><span class="line">        <span class="keyword">this</span>.getArea = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Polygon(sides);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Rectangle</span>(<span class="params">width, height</span>)</span>&#123;</span><br><span class="line">    Polygon.call(<span class="keyword">this</span>, <span class="number">2</span>);</span><br><span class="line">    <span class="keyword">this</span>.width = width;</span><br><span class="line">    <span class="keyword">this</span>.height = height;</span><br><span class="line">    <span class="keyword">this</span>.getArea = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.width * <span class="keyword">this</span>.height;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Rectangle.prototype = <span class="keyword">new</span> Polygon();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> rect = <span class="keyword">new</span> Rectangle(<span class="number">5</span>, <span class="number">10</span>);</span><br><span class="line">alert(rect.sides);   <span class="comment">//2</span></span><br></pre></td></tr></table></figure></p>
<h2 id="惰性载入函数"><a href="#惰性载入函数" class="headerlink" title="惰性载入函数"></a>惰性载入函数</h2><p>上一章的createXHR()函数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createXHR</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> XMLHttpRequest != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> ActiveXObject != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">arguments</span>.callee.activeXString != <span class="string">"string"</span>)&#123;</span><br><span class="line">            <span class="keyword">var</span> versions = [<span class="string">"MSXML2.XMLHttp.6.0"</span>, <span class="string">"MSXML2.XMLHttp.3.0"</span>,</span><br><span class="line">                            <span class="string">"MSXML2.XMLHttp"</span>],</span><br><span class="line">                i, len;</span><br><span class="line">    </span><br><span class="line">            <span class="keyword">for</span> (i=<span class="number">0</span>,len=versions.length; i &lt; len; i++)&#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="keyword">new</span> ActiveXObject(versions[i]);</span><br><span class="line">                    <span class="built_in">arguments</span>.callee.activeXString = versions[i];</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125; <span class="keyword">catch</span> (ex)&#123;</span><br><span class="line">                    <span class="comment">//skip</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">     </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ActiveXObject(<span class="built_in">arguments</span>.callee.activeXString);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">"No XHR object available."</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>if语句不必每次执行，使用惰性载入技巧。</p>
<p>第一种方式就是在函数被调用时再处理函数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createXHR</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> XMLHttpRequest != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        createXHR = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> ActiveXObject != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        createXHR = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;                    </span><br><span class="line">            <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">arguments</span>.callee.activeXString != <span class="string">"string"</span>)&#123;</span><br><span class="line">                <span class="keyword">var</span> versions = [<span class="string">"MSXML2.XMLHttp.6.0"</span>, <span class="string">"MSXML2.XMLHttp.3.0"</span>,</span><br><span class="line">                                <span class="string">"MSXML2.XMLHttp"</span>],</span><br><span class="line">                    i, len;</span><br><span class="line">        </span><br><span class="line">                <span class="keyword">for</span> (i=<span class="number">0</span>,len=versions.length; i &lt; len; i++)&#123;</span><br><span class="line">                    <span class="keyword">try</span> &#123;</span><br><span class="line">                        <span class="keyword">new</span> ActiveXObject(versions[i]);</span><br><span class="line">                        <span class="built_in">arguments</span>.callee.activeXString = versions[i];</span><br><span class="line">                    &#125; <span class="keyword">catch</span> (ex)&#123;</span><br><span class="line">                        <span class="comment">//skip</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        </span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ActiveXObject(<span class="built_in">arguments</span>.callee.activeXString);</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        createXHR = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">"No XHR object available."</span>);</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> createXHR();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xhr1 = createXHR();</span><br><span class="line"><span class="keyword">var</span> xhr2 = createXHR();</span><br></pre></td></tr></table></figure></p>
<p>在第一次调用的过程中，该函数会被覆盖为另一个按合适方式执行的函数，这样任何对原函数的调用都不用再经过执行的分支了。</p>
<p>第二种实现惰性载入的方式是在声明函数时就指定适当的函数。这样，第一次调用函数时就不会损失性能了，而在代码首次加载时会损失一点性能。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> createXHR = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> XMLHttpRequest != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> ActiveXObject != <span class="string">"undefined"</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;                    </span><br><span class="line">            <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">arguments</span>.callee.activeXString != <span class="string">"string"</span>)&#123;</span><br><span class="line">                <span class="keyword">var</span> versions = [<span class="string">"MSXML2.XMLHttp.6.0"</span>, <span class="string">"MSXML2.XMLHttp.3.0"</span>,</span><br><span class="line">                                <span class="string">"MSXML2.XMLHttp"</span>],</span><br><span class="line">                    i, len;</span><br><span class="line">        </span><br><span class="line">                <span class="keyword">for</span> (i=<span class="number">0</span>,len=versions.length; i &lt; len; i++)&#123;</span><br><span class="line">                    <span class="keyword">try</span> &#123;</span><br><span class="line">                        <span class="keyword">new</span> ActiveXObject(versions[i]);</span><br><span class="line">                        <span class="built_in">arguments</span>.callee.activeXString = versions[i];</span><br><span class="line">                        <span class="keyword">break</span>;</span><br><span class="line">                    &#125; <span class="keyword">catch</span> (ex)&#123;</span><br><span class="line">                        <span class="comment">//skip</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        </span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ActiveXObject(<span class="built_in">arguments</span>.callee.activeXString);</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">"No XHR object available."</span>);</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xhr1 = createXHR();</span><br><span class="line"><span class="keyword">var</span> xhr2 = createXHR();</span><br></pre></td></tr></table></figure></p>
<p>这个例子中使用的技巧是创建一个匿名、自执行的函数，用以确定应该使用哪个函数去实现。实际的逻辑都一样。不一样的地方就是第一行代码（使用var定义函数）、新增了自执行的匿名函数，另外每个分支都返回正确的函数定义，以便立即将其赋值给createXHR()。</p>
<p>惰性载入函数的优点是只在分支代码时牺牲一点儿性能。</p>
<h2 id="函数绑定"><a href="#函数绑定" class="headerlink" title="函数绑定"></a>函数绑定</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> handler = &#123;</span><br><span class="line">    message: <span class="string">"Event handled"</span>,</span><br><span class="line">    </span><br><span class="line">    handleClick: <span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>&#123;</span><br><span class="line">        alert(<span class="keyword">this</span>.message);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">"my-btn"</span>);</span><br><span class="line">btn.addEventListener(<span class="string">"click"</span>, handler.handleClick);<span class="comment">//这样会显示undefiend，没有保存handler.handClick()环境，所以this对象最后是指向DOM按钮而非handler。用闭包来解决这个问题</span></span><br><span class="line">btn.addEventListener(<span class="string">"click"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>&#123;</span><br><span class="line">   handler.handleClick(event);</span><br><span class="line">&#125;);<span class="comment">//闭包</span></span><br></pre></td></tr></table></figure>
<p>bind()函数可以将函数绑定到指定环境<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> fn.apply(context, <span class="built_in">arguments</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>如下方式使用<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> fn.apply(context, <span class="built_in">arguments</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> handler = &#123;</span><br><span class="line">    message: <span class="string">"Event handled"</span>,</span><br><span class="line">    </span><br><span class="line">    handleClick: <span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>&#123;</span><br><span class="line">        alert(<span class="keyword">this</span>.message);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">btn.addEventListener(<span class="string">"click"</span>, bind(handler.handleClick, handler));</span><br></pre></td></tr></table></figure></p>
<p>ECMAScript5定义了原生bind()方法。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> handler = &#123;</span><br><span class="line">    message: <span class="string">"Event handled"</span>,</span><br><span class="line"></span><br><span class="line">    handleClick: <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">        alert(<span class="keyword">this</span>.message + <span class="string">":"</span> + event.type);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">"my-btn"</span>);</span><br><span class="line">EventUtil.addHandler(btn, <span class="string">"click"</span>, handler.handleClick.bind(handler));</span><br></pre></td></tr></table></figure></p>
<h2 id="函数柯里化-function-currying"><a href="#函数柯里化-function-currying" class="headerlink" title="函数柯里化 function currying"></a>函数柯里化 function currying</h2><p>基本方法与函数绑定是一样的：使用一个闭包返回一个函数。区别在于，当函数被调用时，返回的函数还需要设置一些传入的参数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">num1, num2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> num1 + num2;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">curriedAdd</span>(<span class="params">num2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> add(<span class="number">5</span>, num2);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(add(<span class="number">2</span>,<span class="number">3</span>));</span><br><span class="line"><span class="built_in">console</span>.log(curriedAdd(<span class="number">3</span>));</span><br></pre></td></tr></table></figure></p>
<p>柯里化函数动态创建步骤：</p>
<p>调用另一个函数并为它传入要柯里化的函数和必要参数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">curry</span>(<span class="params">fn</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> innerArgs = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>);</span><br><span class="line">        <span class="keyword">var</span> finalArgs = args.concat(innerArgs);</span><br><span class="line">        <span class="keyword">return</span> fn.apply(<span class="literal">null</span>, finalArgs);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">num1, num2</span>)</span>&#123;</span><br><span class="line">    retrun num1 + num2;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> curriedAdd = curry(add, <span class="number">5</span>);</span><br><span class="line"><span class="built_in">console</span>.log(curriedAdd(<span class="number">3</span>));<span class="comment">//8</span></span><br></pre></td></tr></table></figure></p>
<p>Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">2</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> innerArgs = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>),</span><br><span class="line">            finalArgs = args.concat(innerArgs);</span><br><span class="line">        <span class="keyword">return</span> fn.apply(context, finalArgs);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> handler = &#123;</span><br><span class="line">    message: <span class="string">"Event handled"</span>,</span><br><span class="line"></span><br><span class="line">    handleClick: <span class="function"><span class="keyword">function</span>(<span class="params">name, event</span>)</span>&#123;</span><br><span class="line">        alert(<span class="keyword">this</span>.message + <span class="string">":"</span> + name + <span class="string">":"</span> + event.type);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">"my-btn"</span>);</span><br><span class="line">EventUtil.addHandler(btn, <span class="string">"click"</span>, bind(handler.handleClick, handler, <span class="string">"my-btn"</span>));</span><br></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> handler = &#123;</span><br><span class="line">    message: <span class="string">"Event handled"</span>,</span><br><span class="line"></span><br><span class="line">    handleClick: <span class="function"><span class="keyword">function</span>(<span class="params">name, event</span>)</span>&#123;</span><br><span class="line">        alert(<span class="keyword">this</span>.message + <span class="string">":"</span> + name + <span class="string">":"</span> + event.type);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">"my-btn"</span>);</span><br><span class="line">EventUtil.addHandler(btn, <span class="string">"click"</span>, handler.handleClick.bind(handler, <span class="string">"my-btn"</span>));</span><br></pre></td></tr></table></figure>
<h1 id="防篡改对象"><a href="#防篡改对象" class="headerlink" title="防篡改对象"></a>防篡改对象</h1><h2 id="不可拓展对象"><a href="#不可拓展对象" class="headerlink" title="不可拓展对象"></a>不可拓展对象</h2><p>preventExtensions(object)方法，不能给对象添加属性和方法。但是可以删除和修改已有成员。</p>
<p>Object.preventExtensions(person);<br>Object.isExtensible(person);</p>
<h2 id="密封的对象"><a href="#密封的对象" class="headerlink" title="密封的对象"></a>密封的对象</h2><p>密封对象不可扩展，已有成员的[[Configurable]]特性将被设置为false。不能删除属性和方法。<br>Object.seal(person);<br>Object.isSeal(person);</p>
<h2 id="冻结的对象"><a href="#冻结的对象" class="headerlink" title="冻结的对象"></a>冻结的对象</h2><p>frozen对象不可拓展又是密封的，而且对象属性的[[Writable]]特性会被设置为false。如果定义[[Set]]函数，访问器属性仍是可写的。<br>Object.frozen(person);<br>Object.isFrozen(person);</p>
<h1 id="高级定时器"><a href="#高级定时器" class="headerlink" title="高级定时器"></a>高级定时器</h1><p>关于定时器要记住的最重要的事情是，指定的时间间隔表示何时将定时器的代码添加到队列，而不是何时执行代码。</p>
<h2 id="重复的定时器"><a href="#重复的定时器" class="headerlink" title="重复的定时器"></a>重复的定时器</h2><p>使用setInterval()创建的定时器，仅当没有该定时器的任何其他代码实例时，才将定时器代码添加到队列中。</p>
<p>这会出现一个问题：如果上一个定时器在执行的过程中，下一个定时器启动。这时候就会跳过这个定时器。</p>
<p>为了避免setInterval()重复定时器的缺点，可以使用链式setTImeout()</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">//要处理的代码</span></span><br><span class="line">    setTimeout(<span class="built_in">arguments</span>.callee, interval); </span><br><span class="line">&#125;, interval);</span><br></pre></td></tr></table></figure>
<p>这段代码可以确保在前一个定时器代码执行完之前，不会向队列插入新的定时器代码，确保不会有任何缺失的间隔。</p>
<h2 id="Yielding-Processes"><a href="#Yielding-Processes" class="headerlink" title="Yielding Processes"></a>Yielding Processes</h2><p>JavaScript的执行时是一个阻塞操作，脚本运行所花时间越久，用户无法与页面交互的时间也就越久。</p>
<p>如果处理循环必须同步完成且数据必须按数据完成，就可以用定时器分割这个循环。这种技术叫做数组分块(Array chunking)技术。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">//取出下一条目并处理</span></span><br><span class="line">    <span class="keyword">var</span> item = array.shift();</span><br><span class="line">    process(item);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//若还有条目，再设置另外一个定时器</span></span><br><span class="line">    <span class="keyword">if</span>(array.length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        setTimeout(<span class="built_in">arguments</span>.callee, <span class="number">100</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;, <span class="number">100</span>);</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> data = [<span class="number">12</span>,<span class="number">123</span>,<span class="number">1234</span>,<span class="number">453</span>,<span class="number">436</span>,<span class="number">23</span>,<span class="number">23</span>,<span class="number">5</span>,<span class="number">4123</span>,<span class="number">45</span>,<span class="number">346</span>,<span class="number">5634</span>,<span class="number">2234</span>,<span class="number">345</span>,<span class="number">342</span>];</span><br><span class="line">        </span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">chunk</span>(<span class="params">array, process, context</span>)</span>&#123;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> item = array.shift();</span><br><span class="line">        process.call(context, item);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span> (array.length &gt; <span class="number">0</span>)&#123;</span><br><span class="line">            setTimeout(<span class="built_in">arguments</span>.callee, <span class="number">100</span>);         </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, <span class="number">100</span>);        </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">printValue</span>(<span class="params">item</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> div = <span class="built_in">document</span>.getElementById(<span class="string">"myDiv"</span>);</span><br><span class="line">    div.innerHTML += item + <span class="string">"&lt;br&gt;"</span>;        </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">chunk(data, printValue);</span><br></pre></td></tr></table></figure>
<p>需要注意的地方是，传递给chunk()的数组是用作一个队列的，因此处理数据的同时，数组中的条目也在改变。如果想保持元素组不变，应该将数组的克隆传递给chunk()<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chunk(data.concat(), printValue);</span><br></pre></td></tr></table></figure></p>
<p>当不传递任何参数调用某个数组的concat()方法时，将返回和原来数组中项目一样的数组。</p>
<p>数组分块的重要性在于它可以将多个项目的处理在执行队列上分开，在每个项目处理之后，给予其它的浏览器处理机会运行，这样就可以避免长时间运行脚本的的错误。</p>
<h2 id="函数节流"><a href="#函数节流" class="headerlink" title="函数节流"></a>函数节流</h2><p>基本思想：某些代码不可以在没有间断的情况下连续重复执行。第一次调用函数，创建一个定时器，在指定的时间间隔之后运行代码。当第二次调用该函数时，它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过过了，这个操作就没有任何意义。如果前一个定时器尚未执行，其实就是将替换为一个新的定时器。</p>
<p>目的：只有在执行函数的请求停止了一段时间之后才执行。<br>以下代码是该模式的基本形式：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> processor = &#123;</span><br><span class="line">    timeoutId: <span class="literal">null</span>,</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//实际进行处理的方法</span></span><br><span class="line">    performProcessing: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="comment">//实际执行的代码</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//初始处理调用的方法</span></span><br><span class="line">    process: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        clearTimeout(<span class="keyword">this</span>.timeoutId);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">var</span> thar = <span class="keyword">this</span>;</span><br><span class="line">        <span class="keyword">this</span>.timeoutId = setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">            that.performProcessing();</span><br><span class="line">        &#125;, <span class="number">100</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//尝试开始执行</span></span><br><span class="line">processor.process();</span><br></pre></td></tr></table></figure></p>
<p>这段代码中创建了一个叫做processor对象。这个对象还有两个方法：process()和performProcessing()。前者是初始化任何处理必须调用的，后者则实际进行应完成的处理。</p>
<p>这个模式可以使用throttle()函数来简化。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">throttle</span>(<span class="params">method, context</span>) </span>&#123;</span><br><span class="line">    clearTimeout(method.tId);</span><br><span class="line">    method.tId = setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        method.call(context);</span><br><span class="line">    &#125;, <span class="number">100</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h1 id="自定义事件"><a href="#自定义事件" class="headerlink" title="自定义事件"></a>自定义事件</h1><p>事件是一种叫做观察者的设计模式。</p>
<p>观察者模式由两类对象组成：主体和观察者。</p>
<p>主体负责发布事件，同时观察者通过订阅这些事件来观察该主体。该模式的一个关键概念是主体并不知道观察者的任何事件也就是说它可以独自存在并正常运作即使观察者不存在。</p>
<p>从另一方面来说，观察者知道主体并能注册事件的回调函数（事件处理程序）。涉及DOM上时，DOM元素便是主体，事件处理程序代码便是观察者。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">EventTarget</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.handlers = &#123;&#125;;    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">EventTarget.prototype = &#123;</span><br><span class="line">    <span class="keyword">constructor</span>: EventTarget,</span><br><span class="line"></span><br><span class="line">    addHandler: function(type, handler)&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="keyword">this</span>.handlers[type] == <span class="string">"undefined"</span>)&#123;</span><br><span class="line">            <span class="keyword">this</span>.handlers[type] = [];</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.handlers[type].push(handler);</span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    fire: <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (!event.target)&#123;</span><br><span class="line">            event.target = <span class="keyword">this</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span>.handlers[event.type] <span class="keyword">instanceof</span> <span class="built_in">Array</span>)&#123;</span><br><span class="line">            <span class="keyword">var</span> handlers = <span class="keyword">this</span>.handlers[event.type];</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>, len=handlers.length; i &lt; len; i++)&#123;</span><br><span class="line">                handlers[i](event);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;            </span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    removeHandler: <span class="function"><span class="keyword">function</span>(<span class="params">type, handler</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span>.handlers[type] <span class="keyword">instanceof</span> <span class="built_in">Array</span>)&#123;</span><br><span class="line">            <span class="keyword">var</span> handlers = <span class="keyword">this</span>.handlers[type];</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>, len=handlers.length; i &lt; len; i++)&#123;</span><br><span class="line">                <span class="keyword">if</span> (handlers[i] === handler)&#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            handlers.splice(i, <span class="number">1</span>);</span><br><span class="line">        &#125;            </span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>使用EventTarget类型的自定义事件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handleMessage</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    alert(<span class="string">"Message received: "</span> + event.message);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> target = <span class="keyword">new</span> EventTarget();</span><br><span class="line"></span><br><span class="line">target.addHandler(<span class="string">"message"</span>, handleMessage);</span><br><span class="line"></span><br><span class="line">target.fire(&#123; <span class="attr">type</span>: <span class="string">"message"</span>, <span class="attr">message</span>: <span class="string">"Hello world!"</span>&#125;);</span><br><span class="line"></span><br><span class="line">target.removeHandler(<span class="string">"message"</span>, handleMessage);</span><br><span class="line"></span><br><span class="line">target.fire(&#123; <span class="attr">type</span>: <span class="string">"message"</span>, <span class="attr">message</span>: <span class="string">"Hello world!"</span>&#125;);</span><br></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">object</span>(<span class="params">o</span>)</span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line">    F.prototype = o;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> F();</span><br><span class="line">&#125;</span><br><span class="line">    </span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritPrototype</span>(<span class="params">subType, superType</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> prototype = object(superType.prototype);   <span class="comment">//create object</span></span><br><span class="line">    prototype.constructor = subType;               <span class="comment">//augment object</span></span><br><span class="line">    subType.prototype = prototype;                 <span class="comment">//assign object</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name, age</span>)</span>&#123;</span><br><span class="line">    EventTarget.call(<span class="keyword">this</span>);</span><br><span class="line">    <span class="keyword">this</span>.name = name;</span><br><span class="line">    <span class="keyword">this</span>.age = age;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">inheritPrototype(Person,EventTarget);</span><br><span class="line"></span><br><span class="line">Person.prototype.say = <span class="function"><span class="keyword">function</span>(<span class="params">message</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.fire(&#123;<span class="attr">type</span>: <span class="string">"message"</span>, <span class="attr">message</span>: message&#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handleMessage</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    alert(event.target.name + <span class="string">" says: "</span> + event.message);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person = <span class="keyword">new</span> Person(<span class="string">"Nicholas"</span>, <span class="number">29</span>);</span><br><span class="line"></span><br><span class="line">person.addHandler(<span class="string">"message"</span>, handleMessage);</span><br><span class="line"></span><br><span class="line">person.say(<span class="string">"Hi there."</span>);</span><br></pre></td></tr></table></figure>
<h1 id="拖放"><a href="#拖放" class="headerlink" title="拖放"></a>拖放</h1><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv1"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"background:red;width:100px;height:100px;position:absolute"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv2"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"background:blue;width:100px;height:100px;position:absolute;left:100px"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> DragDrop = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        </span><br><span class="line"><span class="keyword">var</span> dragging = <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handleEvent</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//get event and target</span></span><br><span class="line">    event = EventUtil.getEvent(event);</span><br><span class="line">    <span class="keyword">var</span> target = EventUtil.getTarget(event);            </span><br><span class="line"></span><br><span class="line">    <span class="comment">//determine the type of event</span></span><br><span class="line">    <span class="keyword">switch</span>(event.type)&#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">"mousedown"</span>:</span><br><span class="line">            <span class="keyword">if</span> (target.className.indexOf(<span class="string">"draggable"</span>) &gt; <span class="number">-1</span>)&#123;</span><br><span class="line">                dragging = target;</span><br><span class="line">            &#125;                     </span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">            </span><br><span class="line">        <span class="keyword">case</span> <span class="string">"mousemove"</span>:</span><br><span class="line">            <span class="keyword">if</span> (dragging !== <span class="literal">null</span>)&#123;</span><br><span class="line">                </span><br><span class="line">                <span class="comment">//assign location</span></span><br><span class="line">                dragging.style.left = event.clientX + <span class="string">"px"</span>;</span><br><span class="line">                dragging.style.top = event.clientY + <span class="string">"px"</span>;                    </span><br><span class="line">            &#125;                    </span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">            </span><br><span class="line">        <span class="keyword">case</span> <span class="string">"mouseup"</span>:</span><br><span class="line">            dragging = <span class="literal">null</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//public interface</span></span><br><span class="line"><span class="keyword">return</span> &#123;            </span><br><span class="line">    enable: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">        EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">        EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    disable: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">        EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">        EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;();</span><br><span class="line"></span><br><span class="line">DragDrop.enable();</span><br></pre></td></tr></table></figure>
<p>元素的位置<br>element.offsetTop<br>element.offsetLeft</p>
<p>鼠标的位置<br>event.clientY<br>event.clientX</p>
<p>原先的代码会让被拖动的元素的左上角在鼠标下方。</p>
<p>现在对鼠标相对元素的位置记录后再次计算元素的绝对位置。<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv1"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"background:red;width:100px;height:100px;position:absolute"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv2"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"background:blue;width:100px;height:100px;position:absolute;left:100px"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> DragDrop = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> dragging = <span class="literal">null</span>,</span><br><span class="line">        diffX = <span class="number">0</span>,</span><br><span class="line">        diffY = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">handleEvent</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//get event and target</span></span><br><span class="line">        event = EventUtil.getEvent(event);</span><br><span class="line">        <span class="keyword">var</span> target = EventUtil.getTarget(event);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//determine the type of event</span></span><br><span class="line">        <span class="keyword">switch</span>(event.type)&#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mousedown"</span>:</span><br><span class="line">                <span class="keyword">if</span> (target.className.indexOf(<span class="string">"draggable"</span>) &gt; <span class="number">-1</span>)&#123;</span><br><span class="line">                    dragging = target;</span><br><span class="line">                    diffX = event.clientX - target.offsetLeft;</span><br><span class="line">                    diffY = event.clientY - target.offsetTop;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mousemove"</span>:</span><br><span class="line">                <span class="keyword">if</span> (dragging !== <span class="literal">null</span>)&#123;</span><br><span class="line"></span><br><span class="line">                    <span class="comment">//assign location</span></span><br><span class="line">                    dragging.style.left = (event.clientX - diffX) + <span class="string">"px"</span>;</span><br><span class="line">                    dragging.style.top = (event.clientY - diffY) + <span class="string">"px"</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mouseup"</span>:</span><br><span class="line">                dragging = <span class="literal">null</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//public interface</span></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        enable: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">        &#125;,</span><br><span class="line"></span><br><span class="line">        disable: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;();</span><br><span class="line"></span><br><span class="line">DragDrop.enable();</span><br></pre></td></tr></table></figure>
<h2 id="添加自定义事件"><a href="#添加自定义事件" class="headerlink" title="添加自定义事件"></a>添加自定义事件</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"status"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv1"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"top:100px;left:0px;background:red;width:100px;height:100px;position:absolute"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myDiv2"</span> <span class="attr">class</span>=<span class="string">"draggable"</span> <span class="attr">style</span>=<span class="string">"background:blue;width:100px;height:100px;position:absolute;top:100px;left:100px"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> DragDrop = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> dragdrop = <span class="keyword">new</span> EventTarget(),</span><br><span class="line">        dragging = <span class="literal">null</span>,</span><br><span class="line">        diffX = <span class="number">0</span>,</span><br><span class="line">        diffY = <span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">handleEvent</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    </span><br><span class="line">        <span class="comment">//get event and target</span></span><br><span class="line">        event = EventUtil.getEvent(event);</span><br><span class="line">        <span class="keyword">var</span> target = EventUtil.getTarget(event);            </span><br><span class="line">    </span><br><span class="line">        <span class="comment">//determine the type of event</span></span><br><span class="line">        <span class="keyword">switch</span>(event.type)&#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mousedown"</span>:</span><br><span class="line">                <span class="keyword">if</span> (target.className.indexOf(<span class="string">"draggable"</span>) &gt; <span class="number">-1</span>)&#123;</span><br><span class="line">                    dragging = target;</span><br><span class="line">                    diffX = event.clientX - target.offsetLeft;</span><br><span class="line">                    diffY = event.clientY - target.offsetTop;</span><br><span class="line">                    dragdrop.fire(&#123;<span class="attr">type</span>:<span class="string">"dragstart"</span>, <span class="attr">target</span>: dragging, <span class="attr">x</span>: event.clientX, <span class="attr">y</span>: event.clientY&#125;);</span><br><span class="line">                &#125;                     </span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">                </span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mousemove"</span>:</span><br><span class="line">                <span class="keyword">if</span> (dragging !== <span class="literal">null</span>)&#123;</span><br><span class="line">                    </span><br><span class="line">                    <span class="comment">//assign location</span></span><br><span class="line">                    dragging.style.left = (event.clientX - diffX) + <span class="string">"px"</span>;</span><br><span class="line">                    dragging.style.top = (event.clientY - diffY) + <span class="string">"px"</span>;   </span><br><span class="line"></span><br><span class="line">                    <span class="comment">//fire custom event</span></span><br><span class="line">                    dragdrop.fire(&#123;<span class="attr">type</span>:<span class="string">"drag"</span>, <span class="attr">target</span>: dragging, <span class="attr">x</span>: event.clientX, <span class="attr">y</span>: event.clientY&#125;);</span><br><span class="line">                &#125;                    </span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">                </span><br><span class="line">            <span class="keyword">case</span> <span class="string">"mouseup"</span>:</span><br><span class="line">                dragdrop.fire(&#123;<span class="attr">type</span>:<span class="string">"dragend"</span>, <span class="attr">target</span>: dragging, <span class="attr">x</span>: event.clientX, <span class="attr">y</span>: event.clientY&#125;);</span><br><span class="line">                dragging = <span class="literal">null</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//public interface</span></span><br><span class="line">    dragdrop.enable = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">            EventUtil.addHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">    &#125;;</span><br><span class="line">        </span><br><span class="line">    dragdrop.disable = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousedown"</span>, handleEvent);</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mousemove"</span>, handleEvent);</span><br><span class="line">            EventUtil.removeHandler(<span class="built_in">document</span>, <span class="string">"mouseup"</span>, handleEvent);</span><br><span class="line">    &#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> dragdrop;</span><br><span class="line">&#125;();</span><br><span class="line"></span><br><span class="line">DragDrop.enable();</span><br><span class="line">                </span><br><span class="line">DragDrop.addHandler(<span class="string">"dragstart"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="built_in">document</span>.getElementById(<span class="string">"status"</span>);</span><br><span class="line">    status.innerHTML = <span class="string">"Started dragging "</span> + event.target.id;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">DragDrop.addHandler(<span class="string">"drag"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="built_in">document</span>.getElementById(<span class="string">"status"</span>);</span><br><span class="line">    status.innerHTML += <span class="string">"&lt;br&gt;Dragged "</span> + event.target.id + <span class="string">" to ("</span> + event.x + <span class="string">","</span> + event.y + <span class="string">")"</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">DragDrop.addHandler(<span class="string">"dragend"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="built_in">document</span>.getElementById(<span class="string">"status"</span>);</span><br><span class="line">    status.innerHTML += <span class="string">"&lt;br&gt;Dropped "</span> + event.target.id + <span class="string">" at ("</span> + event.x + <span class="string">","</span> + event.y + <span class="string">")"</span>;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><ul>
<li>使用惰性载入函数，将任何代码分支推迟到第一次调用函数的时候。</li>
<li>函数绑定可以创建始终在指定环境中运行的函数，同时函数柯里化可以创建已经填了某些参数的函数。</li>
<li><p>将绑定和柯里化组合起来，就可以获得在任意环境中以任意参数执行任意函数的方法。</p>
</li>
<li><p>不可拓展的对象，不允许给对象添加新的属性或方法</p>
</li>
<li>密封的对象，也是不可拓展的对象，不允许删除已有的属性和方法</li>
<li><p>冻结的独享，也是密封的对象，不允许重写对象的成员</p>
</li>
<li><p>定时器代码是放在一个等待区域，知道时间间隔到了之后，将代码添加到JavaScript的处理队列中，等待下一次JavaScript进程空闲的时候被执行。</p>
</li>
<li>每次一段代码执行结束之后，都会有一小段空闲时间进行其他浏览器处理</li>
<li>这种行为意味着，可以使用定时器将长时间运行的脚本切分为一小块一小块可以在以后运行的代码段。这种做法有助于Web应用对用户交互有更积极的响应。</li>
</ul>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/读书笔记/" rel="tag"># 读书笔记</a>
          
            <a href="/tags/js高程/" rel="tag"># js高程</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/09/06/307/" rel="next" title="js高程读书笔记 第21章 Ajax与Comet">
                <i class="fa fa-chevron-left"></i> js高程读书笔记 第21章 Ajax与Comet
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/11/07/311/" rel="prev" title="关于MacBook 15 MD103 连接wifi_5G的问题">
                关于MacBook 15 MD103 连接wifi_5G的问题 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/images/avatar.jpg" alt="何米酥">
            
              <p class="site-author-name" itemprop="name">何米酥</p>
              <p class="site-description motion-element" itemprop="description">Just do...</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">202</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">8</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">78</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/hemisu" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.zhihu.com/people/hemisu" target="_blank" title="知乎">
                      
                        <i class="fa fa-fw fa-globe"></i>知乎</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#本章内容"><span class="nav-number">1.</span> <span class="nav-text">本章内容</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#高级函数"><span class="nav-number">2.</span> <span class="nav-text">高级函数</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#安全的类型检测"><span class="nav-number">2.1.</span> <span class="nav-text">安全的类型检测</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#作用域安全的构造函数"><span class="nav-number">2.2.</span> <span class="nav-text">作用域安全的构造函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#惰性载入函数"><span class="nav-number">2.3.</span> <span class="nav-text">惰性载入函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#函数绑定"><span class="nav-number">2.4.</span> <span class="nav-text">函数绑定</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#函数柯里化-function-currying"><span class="nav-number">2.5.</span> <span class="nav-text">函数柯里化 function currying</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#防篡改对象"><span class="nav-number">3.</span> <span class="nav-text">防篡改对象</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#不可拓展对象"><span class="nav-number">3.1.</span> <span class="nav-text">不可拓展对象</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#密封的对象"><span class="nav-number">3.2.</span> <span class="nav-text">密封的对象</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#冻结的对象"><span class="nav-number">3.3.</span> <span class="nav-text">冻结的对象</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#高级定时器"><span class="nav-number">4.</span> <span class="nav-text">高级定时器</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#重复的定时器"><span class="nav-number">4.1.</span> <span class="nav-text">重复的定时器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Yielding-Processes"><span class="nav-number">4.2.</span> <span class="nav-text">Yielding Processes</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#函数节流"><span class="nav-number">4.3.</span> <span class="nav-text">函数节流</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#自定义事件"><span class="nav-number">5.</span> <span class="nav-text">自定义事件</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#拖放"><span class="nav-number">6.</span> <span class="nav-text">拖放</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#添加自定义事件"><span class="nav-number">6.1.</span> <span class="nav-text">添加自定义事件</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#总结"><span class="nav-number">7.</span> <span class="nav-text">总结</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      
        <div class="back-to-top">
          <i class="fa fa-arrow-up"></i>
          
            <span id="scrollpercent"><span>0</span>%</span>
          
        </div>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; 2015 &mdash; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">何米酥</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







        
      </div>
    </footer>

    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
